#include <QPainter>
#include <QDebug>
#include <QVBoxLayout>
#include <rviz_common/display_context.hpp>
#include <rviz_common/logging.hpp>
#include "rviz_custom_plugins/panels/video_panel.h"


namespace rviz_custom_plugins {


namespace panels {


VideoPanel::VideoPanel(QWidget *parent) : Panel(parent) 
{
    widgetManager = WidgetManager::getInstance();

    videoWidget = new VideoWidget(this);

    auto layout = new QVBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 2);
    layout->addWidget(videoWidget);

    // setLayout(layout);
}

void VideoPanel::onInitialize() {
    rosNode = getDisplayContext()->getRosNodeAbstraction();
    connect(widgetManager, &WidgetManager::widgetShow, this, &VideoPanel::handleWidgetShow);
    setEnabled(false);
    parentWidget()->hide();
}


void VideoPanel::save(Config config) const
{
    Panel::save(config);
    config.mapSetValue("VideoUrl", videoWidget->getVideoUrl());
}


void VideoPanel::load(const Config& config)
{
    Panel::load(config);
    // set video url and play
    QString videoUrl;
    config.mapGetString("VideoUrl", &videoUrl);
    videoWidget->setVideoUrl(videoUrl);
    videoWidget->start();
    // set topic and subscribe
    QString subTopic;
    config.mapGetString("SubTopic", &subTopic);
    subscribe(subTopic);
}


VideoWidget* VideoPanel::getVideoWidget() {
    return videoWidget;
}


void VideoPanel::subscribe(QString topic)
{
    try {
        rclcpp::SubscriptionOptions sub_opts;
        sub_opts.event_callbacks.message_lost_callback =
            [&](rclcpp::QOSMessageLostInfo & info)
        {
            std::ostringstream sstm;
            sstm << "Some messages were lost:\n>\tNumber of new lost messages: " <<
                info.total_count_change << " \n>\tTotal number of messages lost: " <<
                info.total_count;
            RVIZ_COMMON_LOG_WARNING(sstm.str().c_str());
        };

        rclcpp::Node::SharedPtr node = rosNode.lock()->get_raw_node();
        subscriptionPtr = node->create_subscription<VisbotIDBoxArr>(topic.toStdString(), 5,
            [this](const VisbotIDBoxArr::ConstSharedPtr message) {processMessage(message);},
            sub_opts);

    } catch (rclcpp::exceptions::InvalidTopicNameError & e) {
        RVIZ_COMMON_LOG_ERROR("subscribe topic failed");
    }
}


void VideoPanel::processMessage(const VisbotIDBoxArr::ConstSharedPtr message) {
    videoWidget->setVisbotIDBoxArr(message);
}


void VideoPanel::unsubscribe() {
    subscriptionPtr.reset();
}


void VideoPanel::handleWidgetShow(int widgetId, bool isShow) {
    if(widgetId == WidgetManager::GIMBAL_VIDEO_PANEL) {
        if (isShow) {
            setEnabled(true);
            parentWidget()->show();
        } else {
            setEnabled(false);
            parentWidget()->hide();
        }
    }
}


}

}

// Tell pluginlib about this class.  Every class which should be
// loadable by pluginlib::ClassLoader must have these two lines
// compiled in its .cpp file, outside of any namespace scope.
#include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(rviz_custom_plugins::panels::VideoPanel,rviz_common::Panel )
// END_TUTORIAL
